package Beans;

import Beans.util.JsfUtil;
import Beans.util.PaginationHelper;
import Entidades.Client;
import Entidades.Item;
import Entidades.Orderes;
import Entidades.Person;
import Entidades.Product;
import SessionBeans.OrderesFacade;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
//import static util.utilitarioJavaMail.InboxReader.printMessage;

@ManagedBean(name = "orderesController")
@SessionScoped
public class OrderesController implements Serializable {

    private Orderes current;
    private DataModel items = null;
    private ListDataModel itensLista = null;
    @EJB
    private SessionBeans.ProductFacade ejbFacadePro;
    @EJB
    private SessionBeans.OrderesFacade ejbFacade;
    @EJB
    private SessionBeans.ClientFacade CejbFacede;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    private Orderes carrinhoCompra = new Orderes(); //será o pedido feito pelo site... e mandado pro email..
    private ListDataModel CarrinhoItensLista = null;
    private Integer qtd = 0;

    public OrderesController() {
    }

    public void readerMail() {
        Properties props = System.getProperties();
        props.setProperty("mail.store.protocol", "imaps");

        try {

            Session session = Session.getDefaultInstance(props, null);
            Store store = session.getStore("imaps");

            store.connect("imap.gmail.com", "ecommercexml@gmail.com", "3commercexml");
            System.out.println(store);

            Folder inbox = store.getFolder("Inbox");
            inbox.open(Folder.READ_ONLY);
            Message messages[] = inbox.getMessages();
            for (Message message : messages) {
                printMessage(message);
            }

        } catch (NoSuchProviderException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (MessagingException e) {
            e.printStackTrace();
            System.exit(2);
        }
    }

    public Orderes getSelected() {
        if (current == null) {
            current = new Orderes();
            selectedItemIndex = -1;
        }
        return current;
    }

    public ListDataModel getCarrinhoItensLista() {
        return CarrinhoItensLista;
    }

    public void setCarrinhoItensLista(ListDataModel CarrinhoItensLista) {
        this.CarrinhoItensLista = CarrinhoItensLista;
    }

    public Integer getQtd() {
        qtd = this.QtdProdutosCarrinho();
        return qtd;
    }

    public void setQtd(Integer qtd) {
        this.qtd = qtd;
    }

    public Boolean verificaLista() {

        if (carrinhoCompra.getItem() == null) {
            return false;
        }

        return true;
    }

    public Orderes getCarrinhoCompra() {
        return carrinhoCompra;
    }

    public void setCarrinhoCompra(Orderes carrinhoCompra) {
        this.carrinhoCompra = carrinhoCompra;
    }

    public String addCarrinho(Integer id) {
        System.out.println(">>> Carrinho add 1 id: " + id);

        try {
            Product p = new Product();
            p = ejbFacadePro.find(id);
            Item i = new Item();
            System.out.println(">>> Carrinho add  2");
            if ((Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho") == null) {
                System.out.println(">>> Carrinho add 3 ");
                carrinhoCompra = new Orderes();
                List<Item> listaItens = new ArrayList<Item>();

                i.setProduct(p);
                i.setQuanttity(1);
                listaItens.add(i);
                carrinhoCompra.setClient((Client) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCurrent"));
                carrinhoCompra.setItem(listaItens);
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Carrinho", carrinhoCompra);
                System.out.println(">>> Carrinho add 4 ");
            } else {
                carrinhoCompra = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");

                i.setProduct(p);
                i.setQuanttity(1);
                carrinhoCompra.getItem().add(i);
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Carrinho", carrinhoCompra);

            }



        } catch (Exception ex) {
            System.out.println("Error : addCarrinho " + ex);
            FacesMessage msg = new FacesMessage("ERROR", "Error no carrinho " + ex);
            FacesContext.getCurrentInstance().addMessage(null, msg);

        }

        return "/home";
    }

    public void enviarPedido() {
        carrinhoCompra = new Orderes();

        carrinhoCompra = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");

        // TODO: Código aqui!

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Carrinho", null);
    }

    public void deleteProductOnCarrinho(Integer id) {
        carrinhoCompra = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");
        //Item item= new Item();
        Product p = new Product();
        p = ejbFacadePro.findPes(id);
        //i.setProduct(p);
        System.out.println("deleteProductOnCarrinho>>>>id:  " + id);
        System.out.println("deleteProductOnCarrinho>>>>tam lista: " + carrinhoCompra.getItem().size());
        for (int i = 0; i < carrinhoCompra.getItem().size(); i++) {
            System.out.println("deleteProductOnCarrinho>>>>  " + i);
            if (carrinhoCompra.getItem().get(i).getProduct().getID() == id) {
                carrinhoCompra.getItem().remove(i);
            }
        }
        System.out.println("deleteProductOnCarrinho>>>>  " + carrinhoCompra.getItem().size());
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Carrinho", carrinhoCompra);
    }

    public void onCellEdit(CellEditEvent event) {
        Object oldValue = event.getOldValue();
        Object newValue = event.getNewValue();

        if (newValue != null && !newValue.equals(oldValue)) {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    //retorna quantidade de produtos no carrinho
    public Integer QtdProdutosCarrinho() {
        if ((Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho") == null) {
            return 0;

        } else {
            Orderes o = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");
            return o.getItem().size();

        }

    }

    public String CarrinhoLista() {
        System.out.println(">>> Carrinho Lista ");

        try {
            if ((Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho") == null) {
                System.out.println(">>> Lista Vazia ");
                // FacesMessage msg = new FacesMessage("Lista Vazia", "Carrinho Vazio " );
                // FacesContext.getCurrentInstance().addMessage(null, msg);
                this.carrinhoCompra = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");
                this.CarrinhoItensLista = new ListDataModel();
                return "/home";
            } else {
                carrinhoCompra = (Orderes) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("Carrinho");

                this.CarrinhoItensLista = new ListDataModel(carrinhoCompra.getItem());
                return "/MeuCarrinho";
            }

        } catch (NullPointerException e) {
            System.out.println("Error : CarrinhoLista" + e);
            FacesMessage msg = new FacesMessage("ERROR", "Error no carrinho " + e);
            FacesContext.getCurrentInstance().addMessage(null, msg);

            return "/home";

        }
    }

    public static void printMessage(Message message) {
        try {
            // Get the header information  
            String from = ((InternetAddress) message.getFrom()[0])
                    .getPersonal();
            if (from == null) {
                from = ((InternetAddress) message.getFrom()[0]).getAddress();
            }

            System.out.println("FROM: " + from);
            String subject = message.getSubject();
            System.out.println("SUBJECT: " + subject);

            // -- Get the message part (i.e. the message itself) --  
            Part messagePart = message;
            Object content = messagePart.getContent();

            // -- or its first body part if it is a multipart message --  
            if (content instanceof Multipart) {
                messagePart = ((Multipart) content).getBodyPart(0);
                System.out.println("CONTEÚDO: "
                        + messagePart.getContent().toString());
            }

            // -- Get the content type --  
            String contentType = messagePart.getContentType();

            // -- If the content is plain text, we can print it --  
            System.out.println("CONTENT:" + contentType);
            if (contentType.startsWith("text/plain")
                    || contentType.startsWith("text/html")) {
                InputStream is = messagePart.getInputStream();

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is));

                String thisLine = reader.readLine();
                while (thisLine != null) {
                    thisLine = reader.readLine();
                }
            } else {
                byte[] buf = new byte[4096];

                // Define o caminho que salvará o arquivo.  
                //String caminhoBase = System.getProperty("user.dir") +"\\src\\xml\\";
                String caminhoBase = "C:\\WebApplication\\src\\java\\config\\tmp\\";
                System.out.println(caminhoBase);
                Multipart multi = (Multipart) content;



                for (int i = 0; i < multi.getCount(); i++) {

                    String nomeDoArquivo = multi.getBodyPart(i).getFileName();

                    if (nomeDoArquivo != null) {

                        // Imprime o caminho já com o nome do arquivo para ter certeza, e somente se tiver arquivos.  
                        System.out.println("caminho arr " + caminhoBase + nomeDoArquivo);

                        InputStream is = multi.getBodyPart(i).getInputStream();

                        FileOutputStream fos = new FileOutputStream(caminhoBase + nomeDoArquivo);

                        int bytesRead;
                        while ((bytesRead = is.read(buf)) != -1) {
                            fos.write(buf, 0, bytesRead);
                        }

                        fos.close();
                    }
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void onEdit(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Produto foi Editado", null);

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onDelete(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Produto Foi Excuido", null);

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public ListDataModel getItensLista() {

        this.itensLista = new ListDataModel(current.getItem());
        return itensLista;
    }

    public void setItensLista(ListDataModel itensLista) {
        this.itensLista = itensLista;
    }

    public Double valorTotal() {
        Double total = 0.0;
        int tam = 0;

        tam = current.getItem().size();

        if (tam > 0) {
            for (int i = 0; i < tam; i++) {
                total = total + (current.getItem().get(i).getQuanttity() * current.getItem().get(i).getProduct().getPrice());
            }
        }
        String t = total.toString();
        System.out.println("valor: " + t);

        return total;
    }

    public Double ValorTotalItem(int i) {
        Double total = 0.0;
        int tam = current.getItem().size();

        if (i <= tam) {
            for (int x = 0; x < tam; x++) {
                if (x == i) {
                    total = (current.getItem().get(i).getQuanttity() * current.getItem().get(i).getProduct().getPrice());

                }

            }

        }
        String t = total.toString();
        System.out.println("valor: " + t);
        return total;
    }

    public Double CarvalorTotal() {
        Double total = 0.0;
        int tam = 0;

        tam = carrinhoCompra.getItem().size();

        if (tam > 0) {
            for (int i = 0; i < tam; i++) {
                total = total + (carrinhoCompra.getItem().get(i).getQuanttity() * carrinhoCompra.getItem().get(i).getProduct().getPrice());
            }
        }
        String t = total.toString();
        System.out.println("valor: " + t);

        return total;
    }

    public Double CarValorTotalItem(int i) {
        Double total = 0.0;
        int tam = carrinhoCompra.getItem().size();

        if (i <= tam) {
            for (int x = 0; x < tam; x++) {
                if (x == i) {
                    total = (carrinhoCompra.getItem().get(i).getQuanttity() * carrinhoCompra.getItem().get(i).getProduct().getPrice());

                }

            }

        }
        String t = total.toString();
        System.out.println("valor: " + t);
        return total;
    }

    public Client getClidata() {

        Integer aux = ejbFacade.getClient(current);


        return CejbFacede.find(aux);

    }

    private OrderesFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {
                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (Orderes) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        current = new Orderes();
        selectedItemIndex = -1;
        return "Create";
    }

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("OrderesCreated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String createOrder(Orderes O) {
        try {
            getFacade().create(O);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("OrderesCreated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }


    }

    public String prepareEdit() {
        current = (Orderes) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }

    public String update() {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("OrderesUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current = (Orderes) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreatePagination();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("OrderesDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    private void recreatePagination() {
        pagination = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    @FacesConverter(forClass = Orderes.class)
    public static class OrderesControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            OrderesController controller = (OrderesController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "orderesController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            // TODO: no getter methods were found for primary key in your entity class
            //    Entidades.Orderes 
            // and therefore Converter.getKey() method could not be pre-generated.
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            // TODO: no getter methods were found for primary key in your entity class
            //    Entidades.Orderes 
            // and therefore Converter.getKey() method could not be pre-generated.
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Orderes) {
                Orderes o = (Orderes) object;
                return getStringKey(o.getID());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Orderes.class.getName());
            }
        }
    }
}
